package Controllers;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import Entities.MarketingDistributionsEntity;
import GUI.MarketingDistributionsGUI;
import Server.RsWraper;
import Server.Tuple;

/**
 * The Class MarketingDistributionsController.
 * Controller for creating marketing distributions activity.
 */
public class MarketingDistributionsController implements Validate,Observer{
	
	/** The marketing distribution gui. */
	private MarketingDistributionsGUI mDistGui;
	
	/** The marketing distribution ent. */
	private MarketingDistributionsEntity mDistEnt;
	
	/** The previous controller. */
	private MarketingManagerController prev;
	
	/** The tuples. */
	private ArrayList<Tuple> tuples;
	
	/** The flag. */
	private int flag=0;

	/**
	 * Instantiates a new marketing distributions controller.
	 *
	 * @param MarketingDistributionsGui the marketing distributions gui
	 * @param MarketingDistributionsEntity the marketing distributions entity
	 */
	public MarketingDistributionsController(MarketingDistributionsGUI MarketingDistributionsGui,
			MarketingDistributionsEntity MarketingDistributionsEntity) {
		
		this.mDistGui = MarketingDistributionsGui;
		this.mDistEnt = MarketingDistributionsEntity;
		ClientController.setObserver(this);
		this.mDistGui.addButtonAddActionListener(new AddListener());;
		this.mDistGui.addBackButtonActionListener(new BackListener());
		this.mDistGui.addDomainDocumentListener(new DomainDlistener());
		this.mDistGui.addTypeDocumentListener(new TypeDlistener());
		addProductsToCb();
		this.mDistGui.setVisible(true);
	}
	
	/**
	 * Adds the products to the combo box.
	 */
	private void addProductsToCb()
	{
		String query = "SELECT products.name,products.description FROM products";
		try {
			ClientController.observableClient.sendToServer(query);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
	}
	
	/**
	 * Gets the marketing distributions gui.
	 *
	 * @return the marketing distributions gui
	 */
	public MarketingDistributionsGUI getMarketingDistributionsGui() {
		return mDistGui;
	}
	
	/**
	 * Sets the marketing distributions gui.
	 *
	 * @param MarketingDistributionsGui the new marketing distributions gui
	 */
	public void setMarketingDistributionsGui(MarketingDistributionsGUI MarketingDistributionsGui) {
		this.mDistGui = MarketingDistributionsGui;
	}
	
	/**
	 * Gets the marketing distributions entity.
	 *
	 * @return the marketing distributions entity
	 */
	public MarketingDistributionsEntity getMarketingDistributionsEntity() {
		return mDistEnt;
	}
	
	/**
	 * Sets the marketing distributions entity.
	 *
	 * @param MarketingDistributionsEntity the new marketing distributions entity
	 */
	public void setMarketingDistributionsEntity(
			MarketingDistributionsEntity MarketingDistributionsEntity) {
		this.mDistEnt = MarketingDistributionsEntity;
	}
	
	/**
	 * Gets the previous.
	 *
	 * @return the previous
	 */
	public MarketingManagerController getPrev() {
		return prev;
	}


	/**
	 * Sets the previous.
	 *
	 * @param prev the new previous
	 */
	public void setPrev(MarketingManagerController prev) {
		this.prev = prev;
	}

	


	/* (non-Javadoc)
	 * @see Controllers.Validate#validateInput()
	 */
	@Override
	public boolean validateInput() {
		String domain=mDistGui.getDomainTf().getText();
		String type=mDistGui.getTypeTf().getText();
		
		if(domain.equals("")||type.equals(""))
		{
			mDistGui.displayWarningMessage("Please fill all obligatory fields");
			return false;
		}
		return true;
	}
	
	
	/**
	 * The listener interface for receiving add events.
	 * The class that is interested in processing a add
	 * event implements this interface, and the object created
	 * with that class is registered with a component using the
	 * component's <code>addAddListener<code> method. When
	 * the add event occurs, that object's appropriate
	 * method is invoked.
	 *
	 * @see AddEvent
	 */
	class AddListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			if(validateInput())
			{
				String query;
				mDistEnt.setDomain(mDistGui.getDomainTf().getText());
				mDistEnt.setType(mDistGui.getTypeTf().getText());
				mDistEnt.setProduct((String) mDistGui.getProductCb().getSelectedItem());
				mDistEnt.setComments(mDistGui.getCommentsTf().getText());
				
				if(mDistEnt.getProduct().equals(" "))
				query="SELECT distributions.domain FROM distributions WHERE distributions.domain= '"+mDistEnt.getDomain()+"' AND distributions.type= '"+mDistEnt.getType()+"'";
				else
				{
				query="SELECT distributions.domain FROM distributions WHERE distributions.domain= '"+mDistEnt.getDomain()+"' AND distributions.type= '"+mDistEnt.getType()+"' AND distributions.product= '"+mDistEnt.getProduct()+"'";				
				flag=2;
				}
				try {
					ClientController.observableClient.sendToServer(query);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			
			}
		}
		
	}
	
	/* (non-Javadoc)
	 * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
	 */
	@Override
	public void update(Observable o, Object arg) {
		String query = null;
		
		String msg = (String) arg.toString();
	

			if(msg.equals("empty query"))
			{
				if(flag==0)
				{
					//puts a blank option in the first cell in the combo box
					mDistGui.getProductCb().addItem(" ");
					flag=1;
				}
				else{
					query="INSERT INTO distributions (`domain`, `type`,`product`,`comments`) VALUES ('"+mDistEnt.getDomain()+"', '"+mDistEnt.getType()+"', ' ','"+mDistEnt.getComments()+"')";	//Check if there is domain and type with empty product field , if not insert normally, if there is ,update.
					try {
						ClientController.observableClient.sendToServer(query);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
			else
			if(msg.equals("#Server:Action succeded"))	// an update was executed
			{
				if(flag==2)
				{
					query="UPDATE distributions SET `product`='"+mDistEnt.getProduct()+"',`comments`='"+mDistEnt.getComments()+"' WHERE `domain`='"+mDistEnt.getDomain()+"' AND `type`='"+mDistEnt.getType()+"' AND `product`=' '";	
					try {
						ClientController.observableClient.sendToServer(query);
					} catch (IOException e) {
						e.printStackTrace();
				}
					flag=1;
				}
				else
				mDistGui.displayMessage("Distribution added successfuly");
			}
			else	//normal insert
			{
				if(flag==0)
				{
					tuples=new ArrayList<Tuple>();
					
					//puts a blank option in the first cell in the combo box
					mDistGui.getProductCb().addItem(" ");
					tuples.addAll(((RsWraper)arg).getRows());		//appends all products list
					for(int i=0;i<tuples.size();i++)
					{
						mDistGui.getProductCb().addItem(tuples.get(i).get("NAME")+","+tuples.get(i).get("DESCRIPTION"));
					}
					
					flag=1;
				}
				else
					if(flag!=0)
						mDistGui.displayWarningMessage("Distribution error");
			}
			
	}
	
	/**
	 * The listener interface for receiving back events.
	 * The class that is interested in processing a back
	 * event implements this interface, and the object created
	 * with that class is registered with a component using the
	 * component's <code>addBackListener<code> method. When
	 * the back event occurs, that object's appropriate
	 * method is invoked.
	 *
	 * @see BackEvent
	 */
	class BackListener implements ActionListener
	{

		/* (non-Javadoc)
		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
		 */
		@Override
		public void actionPerformed(ActionEvent e) {
			LoginController.mainWindow.setTitle("Marketing manager");
			LoginController.mainWindow.setContentPane(prev.getMarketingManagerGui());
		}
		
	}
	
	/**
	 * The Class DomainDlistener.
	 * Handles changes in the text fields according to the domain text field changes.
	 */
	class DomainDlistener implements DocumentListener
	{

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void changedUpdate(DocumentEvent e) {
			
		}

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void insertUpdate(DocumentEvent e) {
				mDistGui.getTypeTf().setEnabled(true);
			
		}

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void removeUpdate(DocumentEvent e) {
			if(mDistGui.getDomainTf().getText().equals(""))
			{
			mDistGui.getTypeTf().setEnabled(false);
			mDistGui.getProductCb().setEnabled(false);
			mDistGui.getTypeTf().setText(null);
			mDistGui.getProductCb().setSelectedIndex(0);
			}
			
		}
		
	}
	
	/**
	 * The Class TypeDlistener.
	 * Handles changes in the text fields according to the type text field changes.
	 */
	class TypeDlistener implements DocumentListener
	{

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void changedUpdate(DocumentEvent e) {
		
		}

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void insertUpdate(DocumentEvent e) {
				mDistGui.getProductCb().setEnabled(true);
		}

		/* (non-Javadoc)
		 * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent)
		 */
		@Override
		public void removeUpdate(DocumentEvent e) {
			if(mDistGui.getTypeTf().getText().equals(""))
			{
				mDistGui.getProductCb().setEnabled(false);
				mDistGui.getProductCb().setSelectedIndex(0);
			}
			
		}
		
	}
	
}
